package com.carrental.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carrental.common.constant.AuthConstant;
import com.carrental.common.enume.BizCodeEnume;
import com.carrental.common.exception.BusinessException;
import com.carrental.common.utils.JwtUtils;
import com.carrental.crm.dto.CustomerDTO;
import com.carrental.crm.dto.CustomerLoginDTO;
import com.carrental.crm.dto.CustomerRegisterDTO;
import com.carrental.crm.entity.Customer;
import com.carrental.crm.mapper.CustomerMapper;
import com.carrental.crm.service.CustomerService;
import com.carrental.crm.vo.CustomerVO;
import com.carrental.crm.client.IntegrationClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 客户服务实现类
 */
@Service
@Slf4j
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService {

    // 存储验证码的临时Map（实际项目中应该使用Redis）
    private static final Map<String, String> CODE_MAP = new HashMap<>();

    @Resource
    private IntegrationClient integrationClient;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createCustomer(CustomerDTO customerDTO) {
        // 检查用户ID是否已存在客户信息
        Customer existingCustomer = getOne(new LambdaQueryWrapper<Customer>()
                .eq(Customer::getUserId, customerDTO.getUserId())
                .eq(Customer::getDeleted, 0));

        if (existingCustomer != null) {
            throw new BusinessException("该用户已有客户信息");
        }

        // 创建客户实体
        Customer customer = new Customer();
        BeanUtils.copyProperties(customerDTO, customer);

        // 设置默认值
        if (customer.getLevel() == null) {
            customer.setLevel(1); // 默认普通客户
        }
        if (customer.getStatus() == null) {
            customer.setStatus(1); // 默认正常状态
        }
        if (customer.getSource() == null) {
            customer.setSource(1); // 默认来源官网
        }

        customer.setCreateTime(LocalDateTime.now());
        customer.setUpdateTime(LocalDateTime.now());

        // 保存客户信息
        save(customer);
        return customer.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCustomer(CustomerDTO customerDTO) {
        if (customerDTO.getId() == null) {
            throw new BusinessException("客户ID不能为空");
        }

        Customer customer = getById(customerDTO.getId());
        if (customer == null) {
            throw new BusinessException("客户不存在");
        }

        BeanUtils.copyProperties(customerDTO, customer);
        customer.setUpdateTime(LocalDateTime.now());

        return updateById(customer);
    }

    @Override
    public CustomerVO getCustomerById(Long id) {
        Customer customer = getById(id);
        if (customer == null) {
            return null;
        }
        return convertToVO(customer);
    }

    @Override
    public CustomerVO getCustomerByUserId(Long userId) {
        Customer customer = getOne(new LambdaQueryWrapper<Customer>()
                .eq(Customer::getUserId, userId)
                .eq(Customer::getDeleted, 0));

        if (customer == null) {
            return null;
        }
        return convertToVO(customer);
    }

    @Override
    public Page<CustomerVO> pageCustomers(Page<Customer> page, String name, String phone, String idNumber, Integer type,
            Integer level, Integer status) {
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();

        // 添加查询条件
        if (StringUtils.isNotBlank(name)) {
            queryWrapper.like(Customer::getName, name);
        }
        if (StringUtils.isNotBlank(phone)) {
            queryWrapper.like(Customer::getPhone, phone);
        }
        if (StringUtils.isNotBlank(idNumber)) {
            queryWrapper.like(Customer::getIdNumber, idNumber);
        }
        if (type != null) {
            queryWrapper.eq(Customer::getType, type);
        }
        if (level != null) {
            queryWrapper.eq(Customer::getLevel, level);
        }
        if (status != null) {
            queryWrapper.eq(Customer::getStatus, status);
        }

        // 按创建时间降序排序
        queryWrapper.orderByDesc(Customer::getCreateTime);

        // 执行分页查询
        Page<Customer> customerPage = page(page, queryWrapper);

        // 转换为VO
        Page<CustomerVO> voPage = new Page<>();
        BeanUtils.copyProperties(customerPage, voPage, "records");

        List<CustomerVO> voList = new ArrayList<>();
        for (Customer customer : customerPage.getRecords()) {
            voList.add(convertToVO(customer));
        }
        voPage.setRecords(voList);

        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCustomerLevel(Long id, Integer level) {
        if (id == null || level == null) {
            throw new BusinessException("参数不能为空");
        }

        Customer customer = getById(id);
        if (customer == null) {
            throw new BusinessException("客户不存在");
        }

        customer.setLevel(level);
        customer.setUpdateTime(LocalDateTime.now());

        return updateById(customer);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCustomerStatus(Long id, Integer status) {
        if (id == null || status == null) {
            throw new BusinessException("参数不能为空");
        }

        Customer customer = getById(id);
        if (customer == null) {
            throw new BusinessException("客户不存在");
        }

        customer.setStatus(status);
        customer.setUpdateTime(LocalDateTime.now());

        return updateById(customer);
    }

    @Override
    public boolean sendSmsCode(String phone) {
        if (StringUtils.isBlank(phone)) {
            throw new BusinessException("手机号不能为空");
        }

        // 生成6位随机验证码
        String code = generateRandomCode(6);

        // 将验证码存入临时Map（实际项目中应该使用Redis）
        CODE_MAP.put(phone, code);

        // 实际项目中这里应该调用短信服务发送验证码
        // 为了测试方便，这里直接打印验证码
        log.info("向手机号 {} 发送验证码: {}", phone, code);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(CustomerRegisterDTO registerDTO) {
        // 验证验证码
        String code = CODE_MAP.get(registerDTO.getPhone());

        // if (StringUtils.isBlank(code)) {
        // throw new BusinessException("验证码已过期");
        // }
        //
        // if (!code.equals(registerDTO.getCode())) {
        // throw new BusinessException("验证码错误");
        // }

        // 检查手机号是否已注册
        Customer existingCustomer = getOne(new LambdaQueryWrapper<Customer>()
                .eq(Customer::getPhone, registerDTO.getPhone())
                .eq(Customer::getDeleted, 0));

        if (existingCustomer != null) {
            throw new BusinessException("该手机号已注册");
        }

        // 创建客户
        Customer customer = new Customer();
        customer.setPassword(registerDTO.getPassword());
        customer.setName(registerDTO.getUsername());
        customer.setPhone(registerDTO.getPhone());
        customer.setType(1); // 默认个人客户
        customer.setLevel(1); // 默认普通客户
        customer.setStatus(1); // 默认正常状态
        customer.setSource(2); // 来源APP
        customer.setCreateTime(LocalDateTime.now());
        customer.setUpdateTime(LocalDateTime.now());

        // 保存客户信息
        save(customer);

        // 删除验证码
        CODE_MAP.remove(registerDTO.getPhone());

        return true;
    }

    @Override
    public String loginBySms(CustomerLoginDTO loginDTO) {
        // 验证验证码
        // String code = CODE_MAP.get(loginDTO.getPhone());
        //
        // if (StringUtils.isBlank(code)) {
        // throw new BusinessException("验证码已过期");
        // }
        //
        // if (!code.equals(loginDTO.getCode())) {
        // throw new BusinessException("验证码错误");
        // }

        // 查询客户信息
        Customer customer = getOne(new LambdaQueryWrapper<Customer>()
                .eq(Customer::getName, loginDTO.getUsername())
                .eq(Customer::getDeleted, 0));

        if (customer == null) {
            throw new BusinessException("该手机号未注册");
        }

        // 检查客户状态
        if (customer.getStatus() != 1) {
            throw new BusinessException("账号已被禁用");
        }

        if (!customer.getPassword().equals(loginDTO.getPassword())) {
            throw new BusinessException("密码错误");
        }

        // 生成token
        String token = JwtUtils.createToken(customer.getId().toString(), customer.getName());

        // 删除验证码
        CODE_MAP.remove(loginDTO.getPhone());

        return token;
    }

    @Override
    public CustomerVO getCurrentCustomerInfo() {
        // 从请求中获取当前客户ID
        Long customerId = getCurrentCustomerId();
        if (customerId == null) {
            throw new BusinessException("未登录");
        }

        // 获取客户信息
        return getCustomerById(customerId);
    }

    @Override
    public boolean updateCustomerInfo(CustomerDTO customerDTO) {
        // 从请求中获取当前客户ID
        Long customerId = getCurrentCustomerId();
        if (customerId == null) {
            throw new BusinessException("未登录");
        }

        // 获取当前客户信息
        Customer customer = getById(customerId);
        if (customer == null) {
            throw new BusinessException("客户不存在");
        }

        // 更新客户信息
        if (customerDTO.getName() != null) {
            customer.setName(customerDTO.getName());
        }
        if (customerDTO.getPhone() != null) {
            customer.setPhone(customerDTO.getPhone());
        }
        if (customerDTO.getEmail() != null) {
            customer.setEmail(customerDTO.getEmail());
        }
        if (customerDTO.getIdNumber() != null) {
            customer.setIdNumber(customerDTO.getIdNumber());
        }
        if (customerDTO.getIdType() != null) {
            customer.setIdType(customerDTO.getIdType());
        }
        if (customerDTO.getAddress() != null) {
            customer.setAddress(customerDTO.getAddress());
        }
        if (customerDTO.getType() != null) {
            customer.setType(customerDTO.getType());
        }
        if (customerDTO.getRemark() != null) {
            customer.setRemark(customerDTO.getRemark());
        }
        // 添加对新增字段的处理
        if (customerDTO.getRealName() != null) {
            customer.setRealName(customerDTO.getRealName());
        }
        if (customerDTO.getGender() != null) {
            customer.setGender(customerDTO.getGender());
        }
        if (customerDTO.getBirthday() != null) {
            customer.setBirthday(customerDTO.getBirthday());
        }

        customer.setUpdateTime(LocalDateTime.now());

        // 保存更新
        return updateById(customer);
    }

    @Override
    public boolean logout() {
        // 实际项目中可能需要清除token或会话
        // 这里简单返回true
        return true;
    }

    @Override
    public Integer sendVerificationCode(String phoneNumber, String code) {

        // 1.判断60秒间隔发送，防刷
        String _code = redisTemplate.opsForValue().get(AuthConstant.SMS_CODE_CACHE_PREFIX + phoneNumber);
        if (StringUtils.isNotBlank(_code) && System.currentTimeMillis() - Long.parseLong(_code.split("_")[1]) < 60000) {
            // 调用接口小于60秒间隔不允许重新发送新的验证码
            throw new BusinessException("调用接口小于60秒间隔不允许重新发送新的验证码");
        }

        // 2.验证码存入缓存
        // String code = UUID.randomUUID().toString().substring(0, 5);
        int codeNum = 10000 + (int) (Math.random() * 90000);
        code = String.valueOf(codeNum);
        // 验证码缓存到redis中（并且记录当前时间戳）
        redisTemplate.opsForValue().set(AuthConstant.SMS_CODE_CACHE_PREFIX + phoneNumber,
                code + "_" + System.currentTimeMillis(), 10, TimeUnit.MINUTES);
        log.info("发送验证码短信，手机号：{}，验证码：{}", phoneNumber, code);

        if (StringUtils.isBlank(phoneNumber) || StringUtils.isBlank(code)) {
            log.error("发送验证码短信失败：手机号或验证码为空");
            throw new BusinessException("手机号或验证码为空");
        }

        try {
            // 调用integration服务的短信发送接口
            com.carrental.common.result.Result<Boolean> result = integrationClient.sendVerificationCode(phoneNumber,
                    code);
            if (result.getCode() == 200) {
                log.info("验证码短信发送成功");
                return 1;
            } else {
                log.error("验证码短信发送失败：{}", result != null ? result.getMessage() : "返回结果为空");
                throw new BusinessException("验证码短信发送失败");
            }
        } catch (Exception e) {
            log.error("调用短信服务异常", e);
            throw new BusinessException("调用短信服务异常");
        }
    }

    @Override
    public boolean sendNotification(String phoneNumber, Map<String, String> templateParams) {
        return false;
    }

    @Override
    public boolean sendMarketing(String phoneNumber, Map<String, String> templateParams) {
        return false;
    }

    /**
     * 生成随机验证码
     *
     * @param length 验证码长度
     * @return 验证码
     */
    private String generateRandomCode(int length) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    /**
     * 获取当前登录客户ID
     *
     * @return 客户ID
     */
    private Long getCurrentCustomerId() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        String token = request.getHeader("Authorization");

        if (StringUtils.isBlank(token)) {
            return null;
        }

        // 去掉Bearer前缀
        if (token.startsWith("Bearer ")) {
            token = token.substring(7);
        }

        // 解析token
        String customerId = JwtUtils.getUserId(token);
        return customerId != null ? Long.valueOf(customerId) : null;
    }

    /**
     * 将客户实体转换为VO
     *
     * @param customer 客户实体
     * @return 客户VO
     */
    private CustomerVO convertToVO(Customer customer) {
        if (customer == null) {
            return null;
        }

        CustomerVO vo = new CustomerVO();
        BeanUtils.copyProperties(customer, vo);

        // 设置类型名称
        if (customer.getType() != null) {
            switch (customer.getType()) {
                case 1:
                    vo.setTypeName("个人");
                    break;
                case 2:
                    vo.setTypeName("企业");
                    break;
                default:
                    vo.setTypeName("未知");
            }
        }

        // 设置证件类型名称
        if (customer.getIdType() != null) {
            switch (customer.getIdType()) {
                case 1:
                    vo.setIdTypeName("身份证");
                    break;
                case 2:
                    vo.setIdTypeName("护照");
                    break;
                case 3:
                    vo.setIdTypeName("营业执照");
                    break;
                default:
                    vo.setIdTypeName("未知");
            }
        }

        // 设置来源名称
        if (customer.getSource() != null) {
            switch (customer.getSource()) {
                case 1:
                    vo.setSourceName("官网");
                    break;
                case 2:
                    vo.setSourceName("APP");
                    break;
                case 3:
                    vo.setSourceName("小程序");
                    break;
                case 4:
                    vo.setSourceName("电话");
                    break;
                case 5:
                    vo.setSourceName("线下门店");
                    break;
                case 6:
                    vo.setSourceName("第三方平台");
                    break;
                default:
                    vo.setSourceName("未知");
            }
        }

        // 设置等级名称
        if (customer.getLevel() != null) {
            switch (customer.getLevel()) {
                case 1:
                    vo.setLevelName("普通客户");
                    break;
                case 2:
                    vo.setLevelName("VIP客户");
                    break;
                case 3:
                    vo.setLevelName("企业客户");
                    break;
                default:
                    vo.setLevelName("未知");
            }
        }

        // 设置状态名称
        if (customer.getStatus() != null) {
            switch (customer.getStatus()) {
                case 1:
                    vo.setStatusName("正常");
                    break;
                case 2:
                    vo.setStatusName("黑名单");
                    break;
                default:
                    vo.setStatusName("未知");
            }
        }

        // 设置性别名称
        if (customer.getGender() != null) {
            switch (customer.getGender()) {
                case 1:
                    vo.setGenderName("男");
                    break;
                case 2:
                    vo.setGenderName("女");
                    break;
                case 0:
                    vo.setGenderName("保密");
                    break;
                default:
                    vo.setGenderName("未知");
            }
        }

        return vo;
    }
}